package com.webware.one.client;

import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Widget;
import com.webware.one.client.ui.Dialog;

public abstract class UpdateAsyncCallback<T> implements AsyncCallback<T> {
  private enum EStatus {
    EStart, ESuccess, EFailure
  };

  private Timer timer;
  private EStatus status = EStatus.EStart;
  private int timerCount = 0;
  private T result;
  private Throwable caught;
  private static int execCount = 0;

  public UpdateAsyncCallback() {
    execCount++;

    final Widget panel = Dialog.waiting();
    timer = new Timer() {
      @Override
      public void run() {
        if (timerCount++ > 5 || execCount > 1) {
          if (status == EStatus.EFailure) {
            timer.cancel();
            if (--execCount == 0) panel.removeFromParent();
            onUpdateFailure(caught);

          }
          if (status == EStatus.ESuccess) {
            timer.cancel();
            if (--execCount == 0) panel.removeFromParent();
            onUpdateSuccess(result);
          }
        }
      }
    };
    timer.scheduleRepeating(100);
  }

  @Override
  public void onFailure(Throwable caught) {
    this.caught = caught;
    status = EStatus.EFailure;
  }

  @Override
  public void onSuccess(T result) {
    this.result = result;
    status = EStatus.ESuccess;
  }

  public void onUpdateFailure(Throwable caught) {
    Site.handleError(caught);
  }

  public abstract void onUpdateSuccess(T result);
}
